//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//

package com.surenpi.jenkins.client;

import com.fasterxml.jackson.core.JsonParser.Feature;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.collect.Lists;
import com.google.common.io.ByteStreams;
import com.surenpi.jenkins.client.util.EncodingUtils;
import com.surenpi.jenkins.client.util.RequestReleasingInputStream;
import com.surenpi.jenkins.client.util.ResponseUtils;
import com.surenpi.jenkins.client.util.UrlUtils;
import com.surenpi.jenkins.client.validator.HttpResponseValidator;
import java.io.Closeable;
import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
import java.util.List;
import java.util.Map;
import net.sf.json.JSONObject;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.http.Header;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpRequestBase;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.auth.BasicScheme;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.message.BasicHeader;
import org.apache.http.protocol.BasicHttpContext;
import org.apache.http.protocol.HttpContext;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class JenkinsHttpClient implements JenkinsClient, Closeable {
   private final Logger LOGGER;
   private URI uri;
   private CloseableHttpClient client;
   private HttpContext localContext;
   private HttpResponseValidator httpResponseValidator;
   private ObjectMapper mapper;
   private String context;
   private String jenkinsVersion;
   public static final String EMPTY_VERSION = "UNKNOWN";

   public JenkinsHttpClient(URI uri, CloseableHttpClient client) {
      this.LOGGER = LoggerFactory.getLogger(this.getClass());
      this.context = uri.getPath();
      if (!this.context.endsWith("/")) {
         this.context = this.context + "/";
      }

      this.uri = uri;
      this.mapper = this.getDefaultMapper();
      this.client = client;
      this.httpResponseValidator = new HttpResponseValidator();
      this.jenkinsVersion = "UNKNOWN";
      this.LOGGER.debug("uri={}", uri.toString());
   }

   public JenkinsHttpClient(URI uri, HttpClientBuilder builder) {
      this(uri, builder.build());
   }

   public JenkinsHttpClient(URI uri) {
      this(uri, HttpClientBuilder.create());
   }

   public JenkinsHttpClient(URI uri, String username, String password) {
      this(uri, HttpClientBuilder.create(), username, password);
   }

   public JenkinsHttpClient(URI uri, HttpClientBuilder builder, String username, String password) {
      this(uri, addAuthentication(builder, uri, username, password));
      if (StringUtils.isNotBlank(username)) {
         this.localContext = new BasicHttpContext();
         this.localContext.setAttribute("preemptive-auth", new BasicScheme());
      }

   }

   public <T extends BaseModel> T get(String path, Class<T> cls) throws IOException {
      HttpGet getMethod = new HttpGet(UrlUtils.toJsonApiUri(this.uri, this.context, path));
      HttpResponse response = this.client.execute(getMethod, this.localContext);
      this.jenkinsVersion = ResponseUtils.getJenkinsVersion(response);

      BaseModel var5;
      try {
         this.httpResponseValidator.validateResponse(response);
         var5 = this.objectFromResponse(cls, response);
      } finally {
         EntityUtils.consume(response.getEntity());
         this.releaseConnection(getMethod);
      }

      return (T)var5;
   }

   public <T extends BaseModel> List<T> getList(String path, Class<T> itemCls) throws IOException {
      String response = this.get(path);
      return (List)this.mapper.readValue(response, new TypeReference<List<T>>() {
      });
   }

   public String get(String path) throws IOException {
      HttpGet getMethod = new HttpGet(UrlUtils.toJsonApiUri(this.uri, this.context, path));
      HttpResponse response = this.client.execute(getMethod, this.localContext);
      this.jenkinsVersion = ResponseUtils.getJenkinsVersion(response);
      this.LOGGER.debug("get({}), version={}, responseCode={}", new Object[]{path, this.jenkinsVersion, response.getStatusLine().getStatusCode()});

      String var4;
      try {
         this.httpResponseValidator.validateResponse(response);
         var4 = IOUtils.toString(response.getEntity().getContent());
      } finally {
         EntityUtils.consume(response.getEntity());
         this.releaseConnection(getMethod);
      }

      return var4;
   }

   public <T extends BaseModel> T getQuietly(String path, Class<T> cls) {
      try {
         T value = this.get(path, cls);
         return value;
      } catch (IOException e) {
         this.LOGGER.debug("getQuietly({}, {})", new Object[]{path, cls.getName(), e});
         return null;
      }
   }

   public InputStream getFile(URI path) throws IOException {
      HttpGet getMethod = new HttpGet(path);
      HttpResponse response = this.client.execute(getMethod, this.localContext);
      this.jenkinsVersion = ResponseUtils.getJenkinsVersion(response);
      this.httpResponseValidator.validateResponse(response);
      return new RequestReleasingInputStream(response.getEntity().getContent(), getMethod);
   }

   public BaseModel post(String path, Object data, Class cls) throws IOException {
      return this.post(path, data, cls, true);
   }

   public <R extends BaseModel, D> R post(String path, D data, Class<R> cls, boolean crumbFlag) throws IOException {
      HttpPost request = new HttpPost(UrlUtils.toJsonApiUri(this.uri, this.context, path));
      if (crumbFlag) {
         Crumb crumb = (Crumb)this.getQuietly("/crumbIssuer", Crumb.class);
         if (crumb != null) {
            request.addHeader(new BasicHeader(crumb.getCrumbRequestField(), crumb.getCrumb()));
         }
      }

      if (data != null) {
         String value = this.mapper.writeValueAsString(data);
         StringEntity stringEntity = new StringEntity(value, ContentType.APPLICATION_JSON);
         request.setEntity(stringEntity);
      }

      HttpResponse response = this.client.execute(request, this.localContext);
      this.jenkinsVersion = ResponseUtils.getJenkinsVersion(response);

      Object var16;
      try {
         this.httpResponseValidator.validateResponse(response);
         if (cls == null) {
            Object var15 = null;
            return (R)var15;
         }

         R responseObject;
         if (cls.equals(ExtractHeader.class)) {
            ExtractHeader location = new ExtractHeader();
            location.setLocation(response.getFirstHeader("Location").getValue());
            responseObject = (R)location;
         } else {
            responseObject = this.objectFromResponse(cls, response);
         }

         var16 = responseObject;
      } finally {
         EntityUtils.consume(response.getEntity());
         this.releaseConnection(request);
      }

      return (R)var16;
   }

   public void postForm(String path, Map<String, String> data, boolean crumbFlag) throws IOException {
      HttpPost request;
      if (data != null) {
         List<String> queryParams = Lists.newArrayList();

         for(String param : data.keySet()) {
            queryParams.add(param + "=" + EncodingUtils.encodeParam((String)data.get(param)));
         }

         queryParams.add("json=" + EncodingUtils.encodeParam(JSONObject.fromObject(data).toString()));
         String value = this.mapper.writeValueAsString(data);
         StringEntity stringEntity = new StringEntity(value, ContentType.APPLICATION_FORM_URLENCODED);
         request = new HttpPost(UrlUtils.toNoApiUri(this.uri, this.context, path) + StringUtils.join(queryParams, "&"));
         request.setEntity(stringEntity);
      } else {
         request = new HttpPost(UrlUtils.toNoApiUri(this.uri, this.context, path));
      }

      if (crumbFlag) {
         Crumb crumb = (Crumb)this.get("/crumbIssuer", Crumb.class);
         if (crumb != null) {
            request.addHeader(new BasicHeader(crumb.getCrumbRequestField(), crumb.getCrumb()));
         }
      }

      HttpResponse response = this.client.execute(request, this.localContext);
      this.jenkinsVersion = ResponseUtils.getJenkinsVersion(response);

      try {
         this.httpResponseValidator.validateResponse(response);
      } finally {
         EntityUtils.consume(response.getEntity());
         this.releaseConnection(request);
      }

   }

   public HttpResponse postFormWithResult(String path, List<NameValuePair> data, boolean crumbFlag) throws IOException {
      HttpPost request;
      if (data != null) {
         UrlEncodedFormEntity urlEncodedFormEntity = new UrlEncodedFormEntity(data);
         request = new HttpPost(UrlUtils.toNoApiUri(this.uri, this.context, path));
         request.setEntity(urlEncodedFormEntity);
      } else {
         request = new HttpPost(UrlUtils.toNoApiUri(this.uri, this.context, path));
      }

      if (crumbFlag) {
         Crumb crumb = (Crumb)this.get("/crumbIssuer", Crumb.class);
         if (crumb != null) {
            request.addHeader(new BasicHeader(crumb.getCrumbRequestField(), crumb.getCrumb()));
         }
      }

      HttpResponse response = this.client.execute(request, this.localContext);
      this.jenkinsVersion = ResponseUtils.getJenkinsVersion(response);
      return response;
   }

   public String postXml(String path, String xml_data) throws IOException {
      return this.postXml(path, xml_data, true);
   }

   public String postXml(String path, String xml_data, boolean crumbFlag) throws IOException {
      HttpPost request = new HttpPost(UrlUtils.toJsonApiUri(this.uri, this.context, path));
      if (crumbFlag) {
         Crumb crumb = (Crumb)this.getQuietly("/crumbIssuer", Crumb.class);
         if (crumb != null) {
            request.addHeader(new BasicHeader(crumb.getCrumbRequestField(), crumb.getCrumb()));
         }
      }

      if (xml_data != null) {
         request.setEntity(new StringEntity(xml_data, ContentType.create("text/xml", "utf-8")));
      }

      HttpResponse response = this.client.execute(request, this.localContext);
      this.jenkinsVersion = ResponseUtils.getJenkinsVersion(response);

      String var6;
      try {
         this.httpResponseValidator.validateResponse(response);
         var6 = IOUtils.toString(response.getEntity().getContent());
      } finally {
         EntityUtils.consume(response.getEntity());
         this.releaseConnection(request);
      }

      return var6;
   }

   public String postText(String path, String textData, boolean crumbFlag) throws IOException {
      return this.postText(path, textData, ContentType.DEFAULT_TEXT, crumbFlag);
   }

   public String postText(String path, String textData, ContentType contentType, boolean crumbFlag) throws IOException {
      HttpPost request = new HttpPost(UrlUtils.toJsonApiUri(this.uri, this.context, path));
      if (crumbFlag) {
         Crumb crumb = (Crumb)this.get("/crumbIssuer", Crumb.class);
         if (crumb != null) {
            request.addHeader(new BasicHeader(crumb.getCrumbRequestField(), crumb.getCrumb()));
         }
      }

      if (textData != null) {
         request.setEntity(new StringEntity(textData, contentType));
      }

      HttpResponse response = this.client.execute(request, this.localContext);
      this.jenkinsVersion = ResponseUtils.getJenkinsVersion(response);

      String var7;
      try {
         this.httpResponseValidator.validateResponse(response);
         var7 = IOUtils.toString(response.getEntity().getContent());
      } finally {
         EntityUtils.consume(response.getEntity());
         this.releaseConnection(request);
      }

      return var7;
   }

   public void post(String path) throws IOException {
      this.post(path, (Object)null, (Class)null, false);
   }

   public void post(String path, boolean crumbFlag) throws IOException {
      this.post(path, (Object)null, (Class)null, crumbFlag);
   }

   public void postFormJson(String path, Map<String, Object> data, boolean crumbFlag) throws IOException {
      HttpPost request;
      if (data != null) {
         List<String> queryParams = Lists.newArrayList();
         queryParams.add("json=" + EncodingUtils.encodeParam(JSONObject.fromObject(data).toString()));
         String value = this.mapper.writeValueAsString(data);
         StringEntity stringEntity = new StringEntity(value, ContentType.APPLICATION_FORM_URLENCODED);
         request = new HttpPost(this.noapi(path) + StringUtils.join(queryParams, "&"));
         request.setEntity(stringEntity);
      } else {
         request = new HttpPost(this.noapi(path));
      }

      if (crumbFlag) {
         Crumb crumb = (Crumb)this.getQuietly("/crumbIssuer", Crumb.class);
         if (crumb != null) {
            request.addHeader(new BasicHeader(crumb.getCrumbRequestField(), crumb.getCrumb()));
         }
      }

      HttpResponse response = this.client.execute(request, this.localContext);
      this.getJenkinsVersionFromHeader(response);

      try {
         this.httpResponseValidator.validateResponse(response);
      } finally {
         EntityUtils.consume(response.getEntity());
         this.releaseConnection(request);
      }

   }

   private URI noapi(String path) {
      if (!path.toLowerCase().matches("https?://.*")) {
         path = this.urlJoin(this.context, path);
      }

      return this.uri.resolve("/").resolve(path);
   }

   private String urlJoin(String path1, String path2) {
      if (!path1.endsWith("/")) {
         path1 = path1 + "/";
      }

      if (path2.startsWith("/")) {
         path2 = path2.substring(1);
      }

      return path1 + path2;
   }

   private <T extends BaseModel> T objectFromResponse(Class<T> cls, HttpResponse response) throws IOException {
      InputStream content = response.getEntity().getContent();
      byte[] bytes = ByteStreams.toByteArray(content);
      T result = (T)(this.mapper.readValue(bytes, cls));
      return result;
   }

   private ObjectMapper getDefaultMapper() {
      ObjectMapper mapper = new ObjectMapper();
      mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
      mapper.configure(Feature.ALLOW_COMMENTS, true);
      mapper.configure(Feature.ALLOW_UNQUOTED_FIELD_NAMES, true);
      mapper.configure(Feature.ALLOW_SINGLE_QUOTES, true);
      mapper.configure(Feature.ALLOW_UNQUOTED_CONTROL_CHARS, true);
      return mapper;
   }

   public String getJenkinsVersion() {
      return this.jenkinsVersion;
   }

   public boolean isJenkinsVersionSet() {
      return !"UNKNOWN".equals(this.jenkinsVersion);
   }

   public void close() {
      try {
         this.client.close();
      } catch (IOException ex) {
         this.LOGGER.debug("I/O exception closing client", ex);
      }

   }

   private void releaseConnection(HttpRequestBase httpRequestBase) {
      httpRequestBase.releaseConnection();
   }

   protected static HttpClientBuilder addAuthentication(HttpClientBuilder builder, URI uri, String username, String password) {
      if (StringUtils.isNotBlank(username)) {
         CredentialsProvider provider = new BasicCredentialsProvider();
         AuthScope scope = new AuthScope(uri.getHost(), uri.getPort(), "realm");
         UsernamePasswordCredentials credentials = new UsernamePasswordCredentials(username, password);
         provider.setCredentials(scope, credentials);
         builder.setDefaultCredentialsProvider(provider);
         builder.addInterceptorFirst(new PreemptiveAuth());
      }

      return builder;
   }

   private void getJenkinsVersionFromHeader(HttpResponse response) {
      Header[] headers = response.getHeaders("X-Jenkins");
      if (headers.length == 1) {
         this.jenkinsVersion = headers[0].getValue();
      }

   }

   protected HttpContext getLocalContext() {
      return this.localContext;
   }

   protected void setLocalContext(HttpContext localContext) {
      this.localContext = localContext;
   }
}
